﻿using System;
using System.Collections.Generic;
using System.Speech.Synthesis;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Runtime.InteropServices;
using DelicateDict.Classes;
using System.Collections;
namespace DelicateDict
{
    public partial class Options : Form
    {
        public delegate void RefreshWordList(string word, bool IsRemove, string DBword);
        public delegate void ReloadWordList();
        public RefreshWordList refreshwordlistbox;
        public ReloadWordList reloadwordlistbox;
        [DllImport("winmm.dll")]
        private static extern long mciSendString(string strCommand,
        StringBuilder strReturn, int iReturnLength, int bla);
        [DllImport("winmm.dll")]
        public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);
        [DllImport("winmm.dll")]
        public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
        SpeechSynthesizer sp;
        DictType CurrentDictType;
        bool IsSelectedEditWord = false;
        public Options()
        {
            InitializeComponent();
        }

        #region TabSpeechWord
        private void SpeakTool_Click(object sender, EventArgs e)
        {
            //sp = new SpeechSynthesizer();
            if (sp.State == SynthesizerState.Ready)
            {

                sp.Volume = 100;
                sp.SpeakAsync(Paragraph.Text);
            }

        }

        private void pauseTool_Click(object sender, EventArgs e)
        {
            if (sp != null && sp.State == SynthesizerState.Speaking)
            {
                sp.Pause();
                this.pauseTool.Image = global::DelicateDict.Properties.Resources.current_pause;
            }
        }

        private void ResumeTool_Click(object sender, EventArgs e)
        {

            if (sp != null && sp.State == SynthesizerState.Paused)
            {
                this.pauseTool.Image = global::DelicateDict.Properties.Resources.pause;
                sp.Resume();
            }
        }

        private void StopTool_Click(object sender, EventArgs e)
        {
            if (sp != null && sp.State == SynthesizerState.Speaking || sp.State == SynthesizerState.Paused)
            {
                sp.SpeakAsyncCancelAll();
                this.pauseTool.Image = global::DelicateDict.Properties.Resources.pause;
            }
        }
        private void ToolstripVoiceList_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                sp.SelectVoice(ToolstripVoiceList.SelectedItem.ToString());
                // MessageBox.Show(sp.Voice.Name);
            }
            catch (ArgumentException)
            {
                MessageBox.Show("this voice isn't available !");
            }
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            //MessageBox.Show(trackBar1.Value.ToString());
            int NewVolume = ((ushort.MaxValue / 10) * trackBar1.Value);
            // Set the same volume for both the left and the right channels       BUT I JUST WANT TO CHANGE ONE CHANNEL!!
            uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
            // Set the volume
            waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
            //sp.Volume = trackBar1.Value;
            // mciSendString(string.Concat("setaudio MediaFile volume to ", trackBar1.Value), null, 0, 0);
        }


        #endregion

        #region TabOperation
        private void TabOption_Selected(object sender, TabControlEventArgs e)
        {

            OperationOfTab(sender, e);

        }

        private void TabOption_SelectedIndexChanged(object sender, EventArgs e)
        {
           // MessageBox.Show("select change");
        }

        private void TabOption_Validated(object sender, EventArgs e)
        {
            MessageBox.Show("validate");
        }

        private void TabOption_Enter(object sender, EventArgs e)
        {
            OperationOfTab(sender, e);
        }

        private void btnClose_Click(object sender, EventArgs e)
        {

            DialogResult rs = MessageBox.Show("Before Closing, if you've deleted/removed Word.Please update it."
                               + " Please wait if you have so much words", "Notice", MessageBoxButtons.YesNo);
            if (rs == DialogResult.Yes)
            {
                IOFile iof = new IOFile();
                List<string> l = iof.GetAllWordFromDictType(CurrentDictType);
                IComparer<string> cp = new Comparer(CultureInfo.GetCultureInfo("").CompareInfo);
                l.Sort(cp);
                iof.WriteWordFileFromList(CurrentDictType.DBWord, l);
                reloadwordlistbox();
            }
            this.Close();
        }

        private void OperationOfTab(object sender, EventArgs e)
        {
            if (IsSelectedEditWord && this.comboBoxDictype.SelectedIndex != -1)
            {
                DialogResult rs = MessageBox.Show("You're changing Tab, if you've deleted/removed Word.Please update it."
                               + " Please wait if you have so much words", "Notice", MessageBoxButtons.YesNo);
                if (rs == DialogResult.Yes)
                {
                    IOFile iof = new IOFile();
                    List<string> l = iof.GetAllWordFromDictType(CurrentDictType);
                    IComparer<string> cp = new Comparer(CultureInfo.GetCultureInfo("").CompareInfo);
                    l.Sort(cp);
                    iof.WriteWordFileFromList(CurrentDictType.DBWord, l);
                    reloadwordlistbox();
                }
                IsSelectedEditWord = false;
            }
            switch (this.TabOption.SelectedTab.Text)
            {
                case "SpeechOption":
                    if (sp == null) sp = new SpeechSynthesizer();

                    // get current volume for trackbar
                    uint CurrVol = 0;
                    // At this point, CurrVol gets assigned the volume
                    waveOutGetVolume(IntPtr.Zero, out CurrVol);
                    // Calculate the volume
                    ushort CalcVol = (ushort)(CurrVol & 0x0000ffff);
                    // Get the volume on a scale of 1 to 10 (to fit the trackbar)
                    trackBar1.Value = CalcVol / (ushort.MaxValue / 10);


                    // get listvoice of compobox
                    this.ToolstripVoiceList.Items.Clear();
                    IEnumerator<InstalledVoice> str = sp.GetInstalledVoices().GetEnumerator();
                    while (str.MoveNext())
                    {

                        this.ToolstripVoiceList.Items.Add(str.Current.VoiceInfo.Name);
                    }
                    this.ToolstripVoiceList.SelectedText = "Microsoft Anna";
                    //
                    break;

                case "EditWord":
                    // Load dictionary Type
                    IsSelectedEditWord = true;
                    IOFile iof = new IOFile();
                    ArrayOfDictType aodt = iof.GetAllDictType();
                    comboBoxDictype.Items.Clear();
                    foreach (DictType dt in aodt)
                    {
                        comboBoxDictype.Items.Add(dt.DbName);
                    }
                    comboBoxDictype.Text = "  --DictType--  ";
                    CurrentDictType = null;
                    break;

                

            }
        }
        #endregion

        #region Tab EditWord
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (comboBoxDictype.SelectedIndex == -1) return;
            DictType dtype = GetDictTypeFromCbBox();
            if (dtype != null)
            {
                _Database db = new _Database(dtype);

                // if remove from database success, we remove word in wordlistbox
                if (db.Data_Delete(comboBoxWord.Text))
                {
                    IOFile iof = new IOFile();
                    List<string> l = iof.GetAllWordFromDictType(dtype);
                    l.Remove(comboBoxWord.Text);
                    //update wordlistbox
                    refreshwordlistbox(comboBoxWord.Text, true, dtype.DBWord);
                    // update word.index file
                    iof.WriteWordFileFromList(dtype.DBWord, l);
                    //
                    MessageBox.Show("Delete success !");
                    // update new state of richtextbox mean and comboxBox word
                    comboBoxWord.Text = string.Empty;
                    richTextBoxMean.Text = string.Empty;
                }
                db.CloseDatabase();
            }
            dtype = null;
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
            if (comboBoxDictype.SelectedIndex == -1) return;
            DictType dtype = GetDictTypeFromCbBox();
            if (dtype != null)
            {
                _Database db = new _Database(dtype);
                if (!db.CheckKeyExist(comboBoxWord.Text))
                {
                    DialogResult result = MessageBox.Show("Word doesn't exist, do you want to add ?", "Question", MessageBoxButtons.YesNo);
                    if (result == System.Windows.Forms.DialogResult.Yes)
                    {

                        btnAdd_Click(sender, e);
                        db.CloseDatabase();
                        return;
                    }
                    else
                    {
                        db.CloseDatabase();
                        return;
                    }
                }

                if (richTextBoxMean.ReadOnly == true)
                {
                    richTextBoxMean.BorderStyle = BorderStyle.FixedSingle;
                    this.richTextBoxMean.ReadOnly = false;
                    this.richTextBoxMean.BackColor = System.Drawing.SystemColors.Info;
                    EnableControl(true, false, false);
                }
                else
                {

                    if (dtype != null)
                    {
                        db.Data_Update(comboBoxWord.Text, richTextBoxMean.Text.Replace("\n",@"\n"));
                        db.CloseDatabase();
                    }
                    richTextBoxMean.BorderStyle = BorderStyle.None;
                    richTextBoxMean.ReadOnly = true;
                    this.richTextBoxMean.BackColor = System.Drawing.SystemColors.Window;
                    EnableControl(true, true, true);
                }
            }
        }


        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (comboBoxDictype.SelectedIndex == -1) return;
            // check combobox word
            if (comboBoxWord.Text.Equals(string.Empty))
            {
                MessageBox.Show("word can't empty");
                return;
            }

            DictType dtype = GetDictTypeFromCbBox();
            if (dtype != null)
            {
                _Database db = new _Database(dtype);

                // check key have exist in database
                if (db.CheckKeyExist(comboBoxWord.Text))
                {
                    DialogResult result = MessageBox.Show("Word have exist, do you want to edit ?", "Question", MessageBoxButtons.YesNo);
                    if (result == System.Windows.Forms.DialogResult.Yes)
                    {

                        btnEdit_Click(sender, e);
                        db.CloseDatabase();
                        return;
                    }
                    else
                    {
                        db.CloseDatabase();
                        return;
                    }
                }

                if (richTextBoxMean.ReadOnly)
                {
                    richTextBoxMean.BorderStyle = BorderStyle.FixedSingle;
                    richTextBoxMean.ReadOnly = false;
                    richTextBoxMean.Text = string.Empty;
                    this.richTextBoxMean.BackColor = System.Drawing.SystemColors.Info;
                    EnableControl(false, true, false);
                    db.CloseDatabase();
                }
                else
                {

                    IOFile iof = new IOFile();
                    // insert and close db
                    db.Data_Insert(comboBoxWord.Text, richTextBoxMean.Text.Replace("\n", @"\n"));

                    //update wordlistbox
                    refreshwordlistbox(comboBoxWord.Text, false, dtype.DBWord);
                    // add word to word.index file

                    if (!iof.AddWordToFile(comboBoxWord.Text, dtype.DBWord))
                        MessageBox.Show("Error when adding word to file");
                    else MessageBox.Show("Add word success !");
                    richTextBoxMean.ReadOnly = true;
                    richTextBoxMean.BorderStyle = BorderStyle.None;
                    this.richTextBoxMean.BackColor = System.Drawing.SystemColors.Window;
                    EnableControl(true, true, true);
                    db.CloseDatabase();
                }
            }
        }

        private DictType GetDictTypeFromCbBox()
        {
            DictType dtype = new DictType();
            IOFile iof = new IOFile();
            ArrayOfDictType aodt = iof.GetAllDictType();
            foreach (DictType dt in aodt)
            {
                if (comboBoxDictype.SelectedIndex != -1 && dt.DbName == comboBoxDictype.SelectedItem.ToString())
                    dtype = dt;

            }
            return dtype;
        }

        private void comboBoxWord_TextChanged(object sender, EventArgs e)
        {

            if (comboBoxWord.Text != string.Empty)
            {

                /* SearchWord sw = new SearchWord(GetDictTypeFromCbBox());
                 sw.GetIndexSearch(comboBoxWord.Text);
                 if (sw.Index != -1)
                 {
                     DictType dtype = GetDictTypeFromCbBox();
                     // _Database db = new _Database(dtype);
                     richTextBoxMean.Text = _Database.GetMean(comboBoxWord.Text, dtype).Replace(@"\n", "\n");
                 }
                */

            }

        }
        private void EnableControl(bool edit, bool add, bool delete)
        {
            this.btnEdit.Enabled = edit;
            this.btnAdd.Enabled = add;
            this.btnDelete.Enabled = delete;
        }

      
        private void comboBoxWord_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter && comboBoxDictype.SelectedIndex != -1)
            {
                DictType dtype = GetDictTypeFromCbBox();
                // _Database db = new _Database(dtype);
                richTextBoxMean.Text = _Database.GetMean(comboBoxWord.Text, dtype).Replace(@"\n", "\n");
            }
            else
                return;
        }

        private void comboBoxDictype_SelectedIndexChanged(object sender, EventArgs e)
        {
           
        }

        private void comboBoxDictype_SelectedValueChanged(object sender, EventArgs e)
        {
            if (CurrentDictType != null)
            {
                DialogResult rs = MessageBox.Show("You are changing Dictionary Type."
                                 + "\n If you've deleted/removed word, You must update Dictionary WordList before changing."
                                   + "\n Please wait if you have so much words", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (rs == DialogResult.Yes)
                {
                    IOFile iof = new IOFile();
                    List<string> l = iof.GetAllWordFromDictType(CurrentDictType);
                    IComparer<string> cp = new Comparer(CultureInfo.GetCultureInfo("").CompareInfo);
                    l.Sort(cp);
                    iof.WriteWordFileFromList(CurrentDictType.DBWord, l);
                    // update new currentdictype
                    MessageBox.Show("done !");
                    CurrentDictType = GetDictTypeFromCbBox();
                    return;
                }
               
            }
            CurrentDictType = GetDictTypeFromCbBox();
            return;
        }
    }
        #endregion

    /// <summary>
    /// Class Comparer wil compare to sort list.
    /// </summary>
    class Comparer : IComparer<string>
    {
        CompareInfo ci;
        public Comparer(CompareInfo _ci)
        {
            ci = _ci;
        }
        int IComparer<string>.Compare(string x, string y)
        {
            return ci.Compare(x, y, CompareOptions.Ordinal);
        }
    }
   
    
}
